package
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.utils.setTimeout;
	
	import org.aswing.AsWingManager;
	import org.aswing.JButton;
	import org.aswing.JLabel;
	import org.aswing.JOptionPane;
	import org.aswing.JProgressBar;

	[SWF(width="700",height="480")]
	public class Main extends Sprite
	{
		/**
		 * 二维数组，用于存放图片
		 */
		private var maps:Array;
		/**
		 * 图片行数
		 */
		private var row:int=8;
		/**
		 * 图片列数
		 */
		private var colum:int=10;
		/**
		 * 游戏区域坐标
		 */
		private var MarginLeft:Number = 150;
		private var MarginTop:Number = 80;
		/**
		 * 前一次点击的图片
		 */
		private var oldCard:Card;
		/**
		 * 进度条
		 */
		private var progress:JProgressBar;
		/**
		 * 控制进度条长度
		 */
		private var time:Timer;
		/**
		 * 玩家得分
		 */
		private var score:Number;
		/**
		 * 显示得分
		 */
		private var lblScore:JLabel;
		
		public function Main()
		{
			init();
		}
		/**
		 * 初始化swf，构建游戏
		 */
		private function init():void{
			AsWingManager.initAsStandard(this);
			score=0;
			//游戏区域
			maps=new Array(row+2);
			//存放图片id
			var nums:Array=new Array();
			//循环存入图片id
			for(var i:int=0;i<row;i++){
				nums[i]=new Array();
				for(var j:int=0;j<colum;j++){
					if(i==0||i==2||i==4||i==6){
						nums[i][j]=Math.floor(Math.random()*9)+1;
					}else{
						nums[i][j]=nums[i-1][j];
					}
				}
			}
			//打乱图片id
			for (i = 0; i < row; i++) {
				for (j = 0; j < colum; j++) {
					var Rani:uint=Math.floor(Math.random()*row);
					var Ranj:uint=Math.floor(Math.random()*colum);

					var temp:uint=nums[i][j];
					nums[i][j]=nums[Rani][Ranj];
					nums[Rani][Ranj]=temp;
				}
			}
			//maps中存入游戏区域每个位置初始状态(1表示有图片，0表示无图片)
			for(i=0;i<row+2;i++){
				maps[i]=new Array(colum+2);
				for(j=0;j<colum+2;j++){
					if(i==0||j==0||i==row+1||j==colum+1){
						maps[i][j]=0;
					}else{
						maps[i][j]=1;
					}
				}
			}
			//根据id载入图片
			for (i = 0; i < row; i++) {
				for (j = 0; j < colum; j++) {
					var card:Card = new Card(nums[i][j]);
					
					addChild(card);
					card.x=MarginLeft+j*(card.W+2);
					card.y=MarginTop+i*(card.H+2);
					card.setIndex(i+1,j+1);
					card.addEventListener(MouseEvent.CLICK, onClick);
				}
			}
			//重新开始按钮
			var reStartBtn:JButton=new JButton("重新开始");
			reStartBtn.width=80;
			reStartBtn.height=20;
			reStartBtn.x=MarginLeft+(40+2)*colum-80;
			reStartBtn.y=15;
			addChild(reStartBtn);
			reStartBtn.addEventListener(MouseEvent.CLICK,onReStart);
			
			//进度条
			progress=new JProgressBar(0,1,800);
			progress.width=(40+2)*colum-85;
			progress.height=20;
			progress.x=MarginLeft;
			progress.y=15;
			progress.setString("时间");
			progress.setValue(800);
			addChild(progress);
			
			//显示分数
			lblScore=new JLabel("得分:"+score);
			lblScore.setSizeWH(100,20);
			lblScore.x=MarginLeft;
			lblScore.y=37;
			addChild(lblScore);
			
			time=new Timer(100);
			time.addEventListener(TimerEvent.TIMER,onTimer);
			time.start();
		}
		/**
		 * 控制进度条长度
		 * @param TimerEvent
		 */
		private function onTimer(evt:TimerEvent):void{
			if(progress.getValue()>1){
				progress.setValue(progress.getValue()-1);
			}else{
				var time:Timer=Timer(evt.target);
				time.stop();
				stop();
			}
		}
		/**
		 * 时间到,弹出模式窗体提示游戏失败
		 */
		private function stop():void{
			JOptionPane.showMessageDialog("失败","很遗憾,通关失败!!",handler);
		}
		private function handler(result:Number):void{
			reStart();
		}
		/**
		 * 重新开始游戏函数
		 */
		private function reStart():void{
			time.stop();
			var num:uint=this.numChildren;
			//遍历删除子对象
			for(var i:uint=0;i<num;i++){
				removeChildAt(0);
			}
			//重新初始化游戏
			init();
		}
		/**
		 * 按钮单击事件处理,重新开始游戏
		 * @param MouseEvent
		 * @return void
		 */
		private function onReStart(evt:MouseEvent):void{
			reStart();
		}
		/**
		 * 点击图片事件监听函数
		 * @param MouseEvent
		 */
		private function onClick(evt:MouseEvent):void{
			var currentCard:Card=Card(evt.target);
			if(oldCard==null){
				oldCard=currentCard;
				oldCard.isPressed();
			}else{
				oldCard.TargetCard=currentCard;
				
				if (isMatched()) {
					this.score+=10;
					this.lblScore.setText("得分:"+score);
					addChild(oldCard.line)
					oldCard.line.graphics.clear();
					oldCard.line.graphics.lineStyle(2);
					
					oldCard.line.graphics.moveTo(MarginLeft+oldCard.j*(40+2)-22,MarginTop+oldCard.i*(40+2)-22);
					toLink();
				} else {
					oldCard.unPressed();
					oldCard = null;
				}
			}
		}
		private  function toLink():void {
			if(oldCard.Path.length==0){
				oldCard.line.graphics.lineTo(MarginLeft+oldCard.TargetCard.j*(40+2)-22,MarginTop+oldCard.TargetCard.i*(40+2)-22);
			}else{
				//判断两图片与两转折点是否有3点在同一直线上,如果是,则画线只画到其中一点(同时与两图片的X活Y索引相同的一点)
				if((oldCard.Path[0][0]==oldCard.Path[1][0]&&oldCard.Path[0][0]==oldCard.j)||(oldCard.Path[0][0]==oldCard.Path[1][0]&&oldCard.Path[0][0]==oldCard.TargetCard.j)||(oldCard.Path[0][1]==oldCard.Path[1][1]&&oldCard.Path[0][1]==oldCard.i)||(oldCard.Path[0][1]==oldCard.Path[1][1]&&oldCard.Path[0][1]==oldCard.TargetCard.i)){
					if((oldCard.Path[0][0]==oldCard.j&&oldCard.Path[0][1]==oldCard.TargetCard.i)||(oldCard.Path[0][1]==oldCard.i&&oldCard.Path[0][0]==oldCard.TargetCard.j)){
						oldCard.line.graphics.lineTo(MarginLeft+oldCard.Path[0][0]*(40+2)-22,MarginTop+oldCard.Path[0][1]*(40+2)-22);
						oldCard.line.graphics.lineTo(MarginLeft+oldCard.TargetCard.j*(40+2)-22,MarginTop+oldCard.TargetCard.i*(40+2)-22);
					}else{
						oldCard.line.graphics.lineTo(MarginLeft+oldCard.Path[1][0]*(40+2)-22,MarginTop+oldCard.Path[1][1]*(40+2)-22);
						oldCard.line.graphics.lineTo(MarginLeft+oldCard.TargetCard.j*(40+2)-22,MarginTop+oldCard.TargetCard.i*(40+2)-22);
					}
				}else{
					oldCard.line.graphics.lineTo(MarginLeft+oldCard.Path[0][0]*(40+2)-22,MarginTop+oldCard.Path[0][1]*(40+2)-22);
					oldCard.line.graphics.lineTo(MarginLeft+oldCard.Path[1][0]*(40+2)-22,MarginTop+oldCard.Path[1][1]*(40+2)-22);
					oldCard.line.graphics.lineTo(MarginLeft+oldCard.TargetCard.j*(40+2)-22,MarginTop+oldCard.TargetCard.i*(40+2)-22);
				}
			}
			setTimeout(clearLine,250);
		}
		/**
		 * 连线后停顿一定时间再删掉连成功的图片和连接线
		 */
		private function clearLine():void{
			maps[oldCard.i][oldCard.j]=0;
			maps[oldCard.TargetCard.i][oldCard.TargetCard.j]=0;
			removeChild(oldCard);
			removeChild(oldCard.line);
			removeChild(oldCard.TargetCard);
			oldCard = null;
			if(this.numChildren==3){
				time.stop();
				JOptionPane.showMessageDialog("成功","恭喜通关成功!!",handler);
			}
		}
		/**
		 * 判断两点是否可以相连
		 * @return Boolean
		 */
		private function isMatched():Boolean{
			if(oldCard==oldCard.TargetCard||oldCard.id!=oldCard.TargetCard.id){
				return false;
			}
			var point1:Array=new Array(oldCard.j,oldCard.i);
			var point2:Array=new Array(oldCard.TargetCard.j,oldCard.TargetCard.i);
			var r:Boolean=isLineLink(point1,point2);

			if(r){
				return true;
			}else{
				var parr:Array=new Array();
				parr.splice(0);
				
				//把点击的亮点的X和Y直线方向的所有空位的点存入parr
				for(var i:uint=0;i<maps.length;i++){
					if(maps[i][point1[0]]==0){
						parr.push(new Array(point1[0],i));
					}
				}
				for(i=0;i<maps.length;i++){
					if(maps[i][point2[0]]==0){
						parr.push(new Array(point2[0],i));
					}
				}
				for(i=0;i<maps[point1[1]].length;i++){
					if(maps[point1[1]][i]==0){
						parr.push(new Array(i,point1[1]));
					}
				}
				for(i=0;i<maps[point2[1]].length;i++){
					if(maps[point2[1]][i]==0){
						parr.push(new Array(i,point2[1]));
					}
				}
				
				//判断图片之间的空位路线是否只有3条直线组成(如果出现只有两条直线的情况,也就是parr[i]和parr[j]两点是同一个位置所以不影响判断)
				for(i=0;i<parr.length;i++){
					for(var j:uint=0;j<parr.length;j++){
						if(isLineLink(point1,parr[i])&&isLineLink(point2,parr[j])&&isLineLink(parr[i],parr[j])){
							oldCard.Path.push(parr[i]);
							oldCard.Path.push(parr[j]);
							return true;
						}
					}
				}
			}
			return false;
		}
		
		/**
		 * 判断两点之间是否能用X和Y方向的直线连接
		 * @param Array,Array
		 * @return Boolean
		 */
		private function isLineLink(p1:Array,p2:Array):Boolean{
			var result:Boolean;
			var x1:uint=p1[0];
			var y1:uint=p1[1];
			var x2:uint=p2[0];
			var y2:uint=p2[1];
			var temp:Array=new Array();
			if(x1==x2||y1==y2){
				if(Math.abs(x1-x2)+Math.abs(y1-y2)<=1){
					result=true;
				}else{
					temp[0]=x1-x2==0?x1:x1-(x1-x2)/Math.abs((x1-x2));
					temp[1]=y1-y2==0?y1:y1-(y1-y2)/Math.abs((y1-y2));
					
					if(maps[temp[1]][temp[0]]==0){
						result=isLineLink(temp,p2);
					}else{
						result=false;
					}
				}
			}
			return result;
		}
	}
}